def merge_sort(num_list):
    length = len(num_list)
    if length <= 1:
        return num_list

    # 使用循环代替递归
    step = 1 # 从1开始 不断×2和递归版拆分相反
    while step < length:
        left = 0
        while left < length - step:
            print("left：{}".format(left))
            mid = left + step
            right = min(left + 2 * step, length)
            temp_list = merge(num_list[left:mid], num_list[mid:right])
            num_list[left:left + len(temp_list)] = temp_list  # 将归并排序中合并得到的有序列表 temp_list 更新到原始列表 num_list 的相应位置。
            left += 2 * step
        step *= 2
        print("step：{}".format(step))
    return num_list


def merge(left_list, right_list):
    p, q, temp_list = 0, 0, list()

    while p < len(left_list) and q < len(right_list):
        if left_list[p] <= right_list[q]:
            temp_list.append(left_list[p])
            p += 1
        else:
            temp_list.append(right_list[q])
            q += 1

    temp_list += left_list[p:]
    temp_list += right_list[q:]

    return temp_list


if __name__ == '__main__':
    num_list = [6, 5, 3, 1, 8, 7, 2, 4]
    new_list = merge_sort(num_list)
    print('num_list:', new_list)

"""
在归并排序的循环实现中，`step`、`left`、`mid` 和 `right` 是循环中的一些变量，它们有以下含义：

1. **`step`（步长）**:
   - `step` 是归并排序中的步长，它表示每次迭代中子数组的大小。循环的外部使用 `while step < length` 来不断增加步长，直到步长超过列表长度。

2. **`left`（左指针）**:
   - `left` 是指向当前子数组的起始位置的指针。在循环内，`left` 的值随着每次子数组合并而增加。

3. **`mid`（中间指针）**:
   - `mid` 是当前子数组的中间位置的指针。在归并排序中，每次合并两个有序子数组时，`mid` 用于确定左右两个子数组的边界。

4. **`right`（右指针）**:
   - `right` 是指向当前子数组的结束位置的指针。在循环内，`right` 的值随着每次子数组合并而增加。

下面是循环中涉及这些变量的核心代码：

```python
step = 1
while step < length:
    left = 0
    while left < length - step:
        mid = left + step
        right = min(left + 2 * step, length)
        temp_list = merge(num_list[left:mid], num_list[mid:right])
        num_list[left:left + len(temp_list)] = temp_list
        left += 2 * step
    step *= 2
```

在外循环中，`step` 不断翻倍，内循环中，`left` 指向当前子数组的起始位置，`mid` 指向中间位置，`right` 指向结束位置。`temp_list` 存储合并后的有序子数组，然后通过切片操作将其更新到原始列表 `num_list` 中的相应位置。随着循环的进行，`left` 不断增加，表示下一个子数组的起始位置，直到整个列表有序。
"""